#include "sys_tick.h"
#include "nmsis_gcc.h"
#include "core_feature_timer.h"
#include "core_feature_base.h"
#include "core_feature_eclic.h"
#include "log.h"


uint32_t SystemCoretickClock = SYSTEM_CORE_CLOCK;  /* System Clock Frequency (Core Clock) */
#define SYSTICK_1MS		(SystemCoretickClock / 1000)	/* Ticks in 1 millisecond */
__IO uint32_t	gsys_Tick = 0;


void local_SysTimer_SetControlValue(uint32_t mctl)
{
	SysTimer->MTIMECTL = (mctl & SysTimer_MTIMECTL_Msk);
}


uint32_t local_SysTimer_GetControlValue()
{
	return (SysTimer->MTIMECTL & SysTimer_MTIMECTL_Msk);
}




void  local_SysTimer_SetLoadValue(uint32_t value)
{
	 SysTimer->MTIMER = value;
}





void local_SysTimer_SetCompareValue(uint32_t value)
{
    SysTimer->MTIMERCMP = value;
}




 void local__ECLIC_SetShvIRQ(IRQn_Type IRQn, uint32_t shv)
{
    ECLIC->CTRL[IRQn].INTATTR &= ~CLIC_INTATTR_SHV_Msk;
    ECLIC->CTRL[IRQn].INTATTR |= (uint8_t)(shv<<CLIC_INTATTR_SHV_Pos);
}



uint32_t local__ECLIC_GetCfgNlbits(void)
{
    return ((uint32_t)((ECLIC->CFG & CLIC_CLICCFG_NLBIT_Msk) >> CLIC_CLICCFG_NLBIT_Pos));
}


 void local__ECLIC_SetCtrlIRQ(IRQn_Type IRQn, uint8_t intctrl)
{
    ECLIC->CTRL[IRQn].INTCTRL = intctrl;
}

 uint8_t local__ECLIC_GetCtrlIRQ(IRQn_Type IRQn)
{
    return (ECLIC->CTRL[IRQn].INTCTRL);
}


void local__ECLIC_SetLevelIRQ(IRQn_Type IRQn, uint8_t lvl_abs)
{
    uint8_t nlbits = local__ECLIC_GetCfgNlbits();
	
    //uint8_t intctlbits = (uint8_t)__ECLIC_INTCTLBITS;
    uint8_t intctlbits = 4;

    if (nlbits == 0) {
        return;
    }

    if (nlbits > intctlbits) {
        nlbits = intctlbits;
    }
    uint8_t maxlvl = ((1 << nlbits) - 1);
    if (lvl_abs > maxlvl) {
        lvl_abs = maxlvl;
    }
    uint8_t lvl = lvl_abs << (ECLIC_MAX_NLBITS - nlbits);
    uint8_t cur_ctrl = local__ECLIC_GetCtrlIRQ(IRQn);
    cur_ctrl = cur_ctrl << nlbits;
    cur_ctrl = cur_ctrl >> nlbits;
    local__ECLIC_SetCtrlIRQ(IRQn, (cur_ctrl | lvl));
	//ECLIC->CTRL[IRQn].INTCTRL = intctrl;
}




void local__ECLIC_EnableIRQ(IRQn_Type IRQn)
{
	ECLIC->CTRL[IRQn].INTIE |= CLIC_INTIE_IE_Msk;
}


void  local_ECLIC_SetShvIRQ(IRQn_Type IRQn, uint32_t shv)
{

	ECLIC->CTRL[IRQn].INTATTR &= ~CLIC_INTATTR_SHV_Msk;
    ECLIC->CTRL[IRQn].INTATTR |= (uint8_t)(shv<<CLIC_INTATTR_SHV_Pos);

}





void local_ECLIC_EnableIRQ(IRQn_Type IRQn)
{
    ECLIC->CTRL[IRQn].INTIE |= CLIC_INTIE_IE_Msk;
}


void local_SysTimer_Start(void)
{
    SysTimer->MTIMECTL &= ~(SysTimer_MTIMECTL_TIMESTOP_Msk);
}

void local_SysTick_Config(uint64_t ticks)
{

	local_SysTimer_SetLoadValue(0);
    local_SysTimer_SetCompareValue(ticks);
    local_ECLIC_SetShvIRQ(SysTimer_IRQn, ECLIC_NON_VECTOR_INTERRUPT);
    local__ECLIC_SetLevelIRQ(SysTimer_IRQn, 0);
    local_ECLIC_EnableIRQ(SysTimer_IRQn);
    local_SysTimer_Start();
  


}





void systick_Init(void)
{
    
	/* Use core_aon_clk as systick clock */
    local_SysTimer_SetControlValue(local_SysTimer_GetControlValue()|SysTimer_MTIMECTL_CLKSRC_Msk);
  
	/* Set 1ms periodic interrupt */
	local_SysTick_Config(SYSTICK_1MS);

	/* Enable global interrupt */
	//__enable_irq();
	
}




uint32_t getSystick(void)
{
	return gsys_Tick;
}




